package fr.lna.exemple;

import org.apache.log4j.Logger;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import static fr.lna.util.MessageTools.getMessage;

/**
 * Classe pour expérimenter les possiblités de l'injection de Spring
 * <p>
 * Librairies necessaire pour la compilation :
 * <ul>
 * 	<li>context</li>
 * 	<li>beans</li>
 * 	<li>core</li>
 * </ul>
 * Librairies necessaire pour l'execution :
 * <ul>
 * 	<li> Execution : java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory</li>
 *  <li> Execution : java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor</li>
 *  <li>java.lang.ClassNotFoundException: org.springframework.expression.PropertyAccessor</li>
 * </p>
 * <p>
 *
 * </p>
 * @author Rouviere_x
 * @version 1.0
 */
public class ExempleSpring {

	/**
	 * Voir le tuto sur log4j
	 */
	protected Logger log = Logger.getLogger(getClass());
	
	/**
	 * Application contexte basé sur un fichier xml
	 */
	private ApplicationContext xmlContext;
	
	/***
	 * Application contexte basé sur des annotations 
	 */
	private ApplicationContext annotationContext;
	
	/**
	 * Exemple spring avec fichier xml
	 */
	public ExempleSpring(String[] configFiles, String[] packages ) {
		setXmlContext(applicationXmlContext(configFiles));
		setAnnotationContext(applicationAnnotationContext(packages));
	}

	/**
	 * Exmple de construction d'un contexte spring à partir d'un fichier de configuration.
	 * @see ApplicationContext
	 * new ClassPathXmlApplicationContext(configFiles);
	 * @param configFiles
	 */
	private ApplicationContext applicationXmlContext(String... configFiles) {
		log.debug("Création d'un contexte applicatif avec Spring "+configFiles);		
		if (configFiles != null)
			return  new ClassPathXmlApplicationContext(configFiles);
		else
			return new ClassPathXmlApplicationContext();
	}
	
	/**
	 * Exemple de construction d'un contexte à partir d'annotation
	 * 
	 * @param basePackage
	 * @return
	 */
	private ApplicationContext applicationAnnotationContext(String... basePackage) {
		return new AnnotationConfigApplicationContext(basePackage);
	}


	public void setXmlContext(ApplicationContext xmlContext) {
		this.xmlContext = xmlContext;
	}

	public ApplicationContext getXmlContext() {
		return xmlContext;
	}
	
	public void setAnnotationContext(ApplicationContext annotationContext) {
		this.annotationContext = annotationContext;
	}

	public ApplicationContext getAnnotationContext() {
		return annotationContext;
	}

	/**
	 * Un petit main pour la route
	 * @param argv
	 */
	public static void main(String... argv) {
		
		Logger log = Logger.getLogger("main");
		ExempleSpring expl = new ExempleSpring(new String[]{"contexte.xml"}, new String[]{"fr.lna.chess"});
		ApplicationContext xmlCtx = expl.getXmlContext();
		log.info("Contexte XML : "+getMessage(xmlCtx));
		for(String name : xmlCtx.getBeanDefinitionNames()) {
			log.info("Bean["+xmlCtx.getBean(name));		
		}
		log.info("********************************************");
		ApplicationContext annotationCtx = expl.getAnnotationContext();
		log.info("Contexte Annotation : "+getMessage(annotationCtx));
		for(String name : annotationCtx.getBeanDefinitionNames()) {
			log.info("Bean["+annotationCtx.getBean(name));
		}		
		
		
	}
}
